/* * This file is part of Prepay Credit for Android * * Copyright © 2013 Damien O'Reilly * * Prepay Credit for Android is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * Prepay Credit for Android is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Prepay Credit for Android. If not, see <http://www.gnu.org/licenses/>. * * Report bugs or new features at: https://github.com/DamienOReilly/PrepayCredit * Contact the author at: damienreilly@gmail.com */ package damo.three.ie.util; import android.text.Editable; import android.text.Html; import android.text.Spannable; import android.text.style.BulletSpan; import android.text.style.LeadingMarginSpan; import android.text.style.TypefaceSpan; import org.xml.sax.XMLReader; import java.util.ArrayList; /** * Android Html.fromHtml(String) doesn't not support some tags that I'm using e.g. li ul. * By using code from http://blog.mohammedlakkadshaw.com/Handling_Custom_Tags_Using_Html.tagHandler().html * by Mohammed Lakkadshaw, we have support for these tags, when we use: * Html.fromHtml(String, null, new CustomTagHandler()) * <p/> * I just changed the code to use ArrayList instead of the obsolete Vector and made * use of generics to overcome compiler unchecked warnings. */ public class CustomTagHandler implements Html.TagHandler { private final ArrayList<String> mListParents = new ArrayList<String>(); private int mListItemCount = 0; @Override public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) { if (tag.equals("ul") || tag.equals("ol") || tag.equals("dd")) { if (opening) { mListParents.add(tag); } else mListParents.remove(tag); mListItemCount = 0; } else if (tag.equals("li") && !opening) { handleListTag(output); } else if (tag.equalsIgnoreCase("code")) { if (opening) { output.setSpan(new TypefaceSpan("monospace"), output.length(), output.length(), Spannable.SPAN_MARK_MARK); } else { Object obj = getLast(output, TypefaceSpan.class); int where = output.getSpanStart(obj); output.setSpan(new TypefaceSpan("monospace"), where, output.length(), 0); } } } private <T> Object getLast(Editable text, Class<T> kind) { Object[] objs = text.getSpans(0, text.length(), kind); if (objs.length == 0) { return null; } else { for (int i = objs.length; i > 0; i--) { if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) { return objs[i - 1]; } } return null; } } private void handleListTag(Editable output) { if (mListParents.get(mListParents.size() - 1).equals("ul")) { output.append("\n"); String[] split = output.toString().split("\n"); int lastIndex = split.length - 1; int start = output.length() - split[lastIndex].length() - 1; output.setSpan(new BulletSpan(15 * mListParents.size()), start, output.length(), 0); } else if (mListParents.get(mListParents.size() - 1).equals("ol")) { mListItemCount++; output.append("\n"); String[] split = output.toString().split("\n"); int lastIndex = split.length - 1; int start = output.length() - split[lastIndex].length() - 1; output.insert(start, mListItemCount + ". "); output.setSpan(new LeadingMarginSpan.Standard(15 * mListParents.size()), start, output.length(), 0); } } }